function [call,put] = blsprice(S, X, r, T, sig, q)
%BLSPRICE Black-Scholes put and call option pricing.
%   Compute European put and call option prices using a Black-Scholes model.
%
%   [Call,Put] = blsprice(Price, Strike, Rate, Time, Volatility)
%   [Call,Put] = blsprice(Price, Strike, Rate, Time, Volatility, Yield)
%
%   Optional Input: Yield
%
%   Inputs:
%   Price   	- Current price of the underlying asset.
%
%   Strike      - Strike (i.e., exercise) price of the option.
%
%   Rate        - Annualized continuously compounded risk-free rate of return
%                 over the life of the option, expressed as a positive decimal
%                 number.
%
%   Time        - Time to expiration of the option, expressed in years.
%
%   Volatility  - Annualized asset price volatility (i.e., annualized standard
%                 deviation of the continuously compounded asset return),
%                 expressed as a positive decimal number.
%
%   Optional Input:
%   Yield       - Annualized continuously compounded yield of the underlying
%                 asset over the life of the option, expressed as a decimal
%                 number. If Yield is empty or missing. the default value is
%                 zero.
%
%                 For example, this could represent the dividend yield (annual
%                 dividend rate expressed as a percentage of the price of the
%                 security) or foreign risk-free interest rate for options
%                 written on stock indices and currencies, respectively.
%
%   Outputs:
%   Call        - Price (i.e., value) of a European call option.
%
%   Put         - Price (i.e., value) of a European put option.
%
%   Example:
%      Consider European stock options with an exercise price of $95 that
%      expire in 3 months. Assume the underlying stock pays no dividends, is
%      trading at $100, and has a volatility of 50% per annum, and that the
%      risk-free rate is 10% per annum. Using this data,
%
%      [Call, Put] = blsprice(100, 95, 0.1, 0.25, 0.5)
%      Call =
%         13.6953      % or $13.70
%      Put =
%          6.3497      % or $6.35
%
%      The S&P 100 index currently stands at 585 and has a volatility of 25%
%      per annum. The risk-free rate of interest is 5% per annum and the index
%      provides a dividend yield of 4.5% per annum. Calculate the value of a
%      three-month European call and put with strike price 600.
%
%      [Call, Put] = blsprice(585, 600, .05, .25, .25, .045)
%      Call =
%         22.6716      % or $22.67
%      Put =
%         36.7626      % or $36.76
%
%   Notes:
%    (1) Any input argument may be a scalar, vector, or matrix. If a scalar,
%        then that value is used to price all options. If more than one input
%        is a vector or matrix, then the dimensions of those non-scalar inputs
%        must be the same.
%    (2) Ensure that Rate, Time, Volatility, and Yield are expressed in
%        consistent units of time.
%
%   See also BLSIMPV, BLSDELTA, BLSGAMMA, BLSLAMBDA, BLSTHETA, BLSRHO.

% Copyright 1995-2005 The MathWorks, Inc.
% $Revision: 1.8.2.8 $   $Date: 2008/04/18 21:17:06 $

%
% References:
%   Hull, J.C., "Options, Futures, and Other Derivatives", Prentice Hall,
%     5th edition, 2003.
%   Luenberger, D.G., "Investment Science", Oxford Press, 1998.
%

%
% Input argument checking & default assignment.
%

if nargin < 5
    error('Finance:blsprice:InsufficientInputs', ...
        'Specify Price, Strike, Rate, Time, and Volatility.')
end

if (nargin < 6) || isempty(q)
    q = zeros(size(S));
end

message = blscheck('blsprice', S, X, r, T, sig, q);
error(message);


% Perform scalar expansion & guarantee conforming arrays.
try
    [S, X, r, T, sig, q] = finargsz('scalar', S, X, r, T, sig, q);
catch
    error('Finance:blsprice:InconsistentDimensions', ...
        'Inputs must be scalars or conforming matrices.')
end


% Double up on fcn calls since blsprice calculates both calls and puts. Do
% this only if nargout>1
NumOpt = numel(S);
callSpec = {'call'};
callSpec = callSpec(ones(NumOpt,1));
putSpec = {};
if(nargout)>1
    putSpec = {'put'};
    putSpec = putSpec(ones(NumOpt,1));
end
OptSpec = [callSpec;putSpec];

% blsprice deals only with option pricing
OutSpec = {'price'};

% blspriceeng works with columns. Get sizes, turn to columns, run engine,
% and finally turn to arrays again:
[m, n] = size(S);

% double up the rest of the input args
if(nargout>1)
    [S, X, r, T, sig, q] = deal([S(:);S(:)], [X(:);X(:)], [r(:);r(:)], ...
        [T(:);T(:)], [sig(:);sig(:)], [q(:);q(:)]);
end

% call eng fuction
price = blspriceeng(OutSpec, OptSpec(:), S(:), X(:), r(:), T(:), sig(:), q(:));

% Now separate calls from puts
call = price{1}(1:NumOpt);
call = reshape(call, m, n);

if(nargout>1)
    put = price{1}(NumOpt+1:end);
    put  = reshape(put, m, n);
end


